<?php
/**
 * Geneone: Content Management Framework
 * Metasite Namespace
 *
 * http://geneone.neondragon.net/
 *
 * @package Geneone
 * @author Khlo
 * @version 1.0
 * @copyright 2004-2006 Geneone Development Team
 */
 
class Gene_Namespace_Meta {
	var $pages;
	
	/**
	 * Calls page in this namespace.
	 *
	 * @static
	 * @var $id string Page ID in Namespace
	 * @var $action array Action Argument String
	 * @return bool Status
	 */
	function call($id, $action=array()) {
		$tpl =& Gene::getTemplate();
		$db =& Gene::getDatabase();
		
		if ($info = Gene_Namespace_Meta::getInfo($id)) {
			/* The default action is "view" */
			if (!isset($action[1])) {
				$action[1] = "view";
			}
			
			$actions = Gene_Namespace_Meta::getAllowedActions($id, $action);
			if (!isset($actions[$action[1]])) {
				return false;
			}
			
			// Set a flag on the current action
			foreach ($actions as $j => $k) {
				if ($k[0] == $action[1]) {
					$actions[$j][2] = true;
				}
			}
			
			$tpl->assign("actions", $actions);
			
			/* Generate navcrumbs */
			$crumbs = array();
			if ($info['parentcsv'] != "-1") {
				$crumbs = $db->queryAll("SELECT metaid, metaname, title, parent FROM ".Gene::tableName("meta")." WHERE metaid IN (".$info['parentcsv'].")");
			}
			
			// Start off with the root root
			$crumbcode = '&raquo; <a href="'.Gene::getSetting("gene_uri").'">'.Gene::getSetting("gene_name").'</a>';
			
			foreach ($crumbs as $i) {
				if ($i['parent'] == "-1") {
					$tpl->assign ("navroot", $i);
				}
				
				$crumbcode .= ' &raquo; <a href="'.Gene::makeLink(Gene::metaId($i['metaname'])).'">'.$i['title'].'</a>';
			}
			
			// Finally the current page
			$crumbcode .= ' &raquo; '.$info['title'];
			
			/* Navigation */
			$bits = explode (",", $info['parentcsv']);
			if ($info['parentcsv'] == "-1") {
				$tpl->assign ("navroot", $info);
				$root = $info['metaid']; // If this is root, use this item's id as root
			} else {
				$root = $bits[0]; // otherwise use first entry in list of parents
			}
			
			$q = $db->prepare ("SELECT metaid, metaname, title FROM ".Gene::tableName("meta")." WHERE parent=? ORDER BY title ASC");
			$res = $q->execute(array($info['parent']));
			$currentlevel = $res->fetchAll();
			$res->free();
			
			$q = $db->prepare ("SELECT metaid, metaname, title FROM ".Gene::tableName("meta")." WHERE parent=? ORDER BY title ASC");
			$res = $q->execute(array($info['metaid']));
			$childs = $res->fetchAll();
			$res->free();
			
			$tpl->assign ("sectionnavtitle", "Community Portal");
			$tpl->assign ("parentlevels", $crumbs);
			$tpl->assign ("currentlevel", $currentlevel);
			$tpl->assign ("childlevel", $childs);
			
			$tpl->append ("portlets", "metanav");
			
			$tpl->assign ("info", $info);
	
			$tpl->assign ("navcrumbs", $crumbcode);
			$tpl->assign ("pagetitle", $info['title']);
			
			switch ($action[1]) {
				case 'view':
					return Gene_Namespace_Meta::callView($id);
					break;
				case 'edit':
					return Gene_Namespace_Meta::callEdit($id);
					break;
				case 'new':
					return Gene_Namespace_Meta::callNew($id);
					break;
			}
		} else {
			return false;
		}
	}
	
	/**
	 * Call View Method
	 * 
	 * @static
	 * @var $id string Page ID in Namespace
	 * @return bool Status
	 */
	function callView($id) {
		$tpl =& Gene::getTemplate();
		
		if ($info = Gene_Namespace_Meta::getInfo($id)) {
			$tpl->assign ("body", $tpl->parse($info['content']));
		}
		
		$tpl->assign ("curlbase", Gene::makeLink(Gene::metaID($id)));
		$tpl->assign ("finalbody", $tpl->fetch("meta/view"));
		
		return true;
	}
	
	/**
	 * Call Edit Method
	 * 
	 * @static
	 * @var $id string Page ID in Namespace
	 * @return bool Status
	 */
	function callEdit($id) {
		$tpl =& Gene::getTemplate();
		
		if ($_SERVER['REQUEST_METHOD'] == 'POST') {
			$title = Gene_Request::getString("pagetitle", GENE_REQUEST_POST);
			$content = Gene_Request::getString("pagecontent", GENE_REQUEST_POST);
			if (Gene_Namespace_Meta::updatePage($id, $title, $content)) {
				header ("Location: ".Gene::makeLink(Gene::metaID($id)));
				exit();
			} else {
				$tpl->assign ("finalbody", $tpl->fetch("errors/operror"));
			}
		} else {
			$tpl->assign ("curlbase", Gene::makeLink(Gene::metaID($id)));
			$tpl->assign ("finalbody", $tpl->fetch("meta/edit"));
		}
		
		return true;
	}
	
	/**
	 * Call New Page Method
	 * 
	 * @static
	 * @var $id string Page ID in Namespace
	 * @return bool Status
	 */
	function callNew($id) {
		$tpl =& Gene::getTemplate();
		
		if ($_SERVER['REQUEST_METHOD'] == 'POST') {
			$parentname = Gene_Request::getString ("parentmetaname", GENE_REQUEST_POST);
			if ($parent = Gene_Namespace_Meta::getInfo($parentname)) {
				$title = Gene_Request::getString("pagetitle", GENE_REQUEST_POST);
				$content = Gene_Request::getString("pagecontent", GENE_REQUEST_POST);
				
				if ($newid = Gene_Namespace_Meta::addPage($title, $content, $parentname)) {
					header ("Location: ".Gene::makeLink(Gene::metaID($newid)));
					exit();
				} else {
					$tpl->assign ("finalbody", $tpl->fetch("errors/operror"));
				}
			} else {
				$tpl->assign ("finalbody", $tpl->fetch("errors/operror"));
			}
		} else {
			$tpl->assign ("curlbase", Gene::makeLink(Gene::metaID($id)));
			$tpl->assign ("finalbody", $tpl->fetch("meta/new"));
		}
		
		return true;
	}
	
	/**
	 * Adds a metasite page.
	 * 
	 * @static
	 * @var $title string Page Title
	 * @var $content string Page Content
	 * @var $parentid string Parent ID
	 * @return string/bool New ID on success; otherwise false
	 */
	function addPage($title, $content, $parentid) {
		if ($parent = Gene_Namespace_Meta::getInfo($parentid)) {
			$db =& Gene::getDatabase();
			
			// Generate a metaname
			$metaname = Gene_Namespace_Meta::generateAlias($title);
			
			// Check for existing pages with that metaname
			$q = $db->prepare ("SELECT COUNT(metaid) AS num FROM ".Gene::tableName("meta")." WHERE metaname=? OR metaname LIKE ?");
			$res = $q->execute(array($metaname, $metaname.'%'));
			$count = $res->fetchOne();
			$res->free();

			if ($count > 0) {
				$metaname = $metaname.$count;
			}

			$newid = $db->nextId(Gene::tableName("meta"));
			
			if ($parent['parentcsv'] == "-1") {
				$parentcsv = $parent['metaid'];
			} else {
				$parentcsv = $parent['parentcsv'].",".$parent['metaid'];
			}
			
			$db->extended->autoExecute(
				Gene::tableName("meta"),
				array(
					"metaid" => $newid,
					"metaname" => $metaname,
					"title" => $title,
					"content" => $content,
					"timestamp" => time(),
					"parent" => $parent['metaid'],
					"parentcsv" => $parentcsv
				),
				MDB2_AUTOQUERY_INSERT
			);
			
			return $metaname;
		} else {
			// Parent does not exist. Fail.
			return false;
		}
	}
	
	/**
	 * Updates a metasite page.
	 * 
	 * @static
	 * @var $id string Page ID in Namespace
	 * @var $title string Page Title
	 * @var $content string Page Content
	 * @return bool Status
	 */
	function updatePage($id, $title, $content) {
		$db =& Gene::getDatabase();
		$res = $db->extended->autoExecute(
			Gene::tableName("meta"),
			array(
				"title" => $title,
				"content" => $content,
				"timestamp" => time(),
			),
			MDB2_AUTOQUERY_UPDATE,
			"metaname=".$db->quote($id).""
		);
		
		if ($res) {
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * Automatically generates an meta name.
	 *
	 * @static
	 * @var $text string Original Text
	 * @var $chars int Maximum Slug Length
	 * @return string Alias
	 */
	function generateAlias($text, $chars=60) {
		$slug = preg_replace('/\s\s+/', ' ', preg_replace("/[^a-zA-Z0-9 ]/", "", $text));
		if (strlen($slug) > $chars) {
			$slug = substr($slug, 0, $chars);
			$s = explode(" ", $slug);
			$c = count($s) - 1;
			unset($s[$c]);
			$slug = implode(" ", $s);
		}

		return str_replace(" ", "_", ucwords(strtolower($slug)));
	}
	
	/**
	 * Return allowed actions for Page ID
	 *
	 * @static
	 * @var $id string Page ID in Namespace
	 * @return array Allowed Actions for Page ID
	 */
	function &getAllowedActions($id) {
		$actions = array("view" => array("view", "View"));
		
		// Users with namespaces.meta.edit can edit
		$user =& Gene::getUser();
		if ($user->hasPermission("namespaces.meta.edit")) {
			$actions['edit'] = array("edit", "Edit");
		}
		if ($user->hasPermission("namespaces.meta.new")) {
			$actions['new'] = array("new", "New");
		}
	
		return $actions;
	}
	
	/**
	 * Exports document as XML.
	 *
	 * @var $id string Page ID
	 *
	 * @return boolean Status
	 */
	function exportXml($id) {
		return false;
	}
	
	/**
	 * Runs web services.
	 *
	 * @var $method string Method to Call
	 * @return array/bool Result
	 */
	function runWebServices($method) {
		return false;
	}
	
	/**
	 * Returns whether search is supported by this namespace
	 *
	 * @return bool Searchable Status
	 */
	function isSearchable() {
		return false;
	}
	
	/**
	 * Perform a search in this namespace
	 *
	 * @var $query string Search Term
	 * @var $start integer Result Offset
	 * @var $limit integer Number of Results
	 * @return array Results
	 */
	function search($query, $start=0, $limit=30) {
		return array();
	}
	
	/**
	 * Returns data for a page
	 *
	 * @var $id string Page ID
	 */
	function getInfo($id) {
		$db =& Gene::getDatabase();
		static $pages = array();
		
		if (isset($pages[$id])) {
			return $pages[$id];
		}
		
		// Clear up ID
		$q = $db->prepare ("SELECT * FROM ".Gene::tableName("meta")." WHERE metaname=?");
		$res = $q->execute(array($id));
		if ($row = $res->fetchRow()) {
			$res->free();
			$pages[$id] = $row;
			return $row;
		} else {
			return false;
		}
	}
	
	/* This namespace does not implement intelliAnswer */
	function intelliAnswer($phrase) { return false; }
}

?>